<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
                "http://www.w3.org/TR/html4/strict.dtd">
<html style="overflow-y:scroll;border:0px none;padding:0;margin:0;">
<head>
	<title>dojo.window.scrollIntoView Test</title>

	<style type="text/css">
		@import "../../resources/dojo.css";
		FIELDSET { border:2px groove black; display:inline; padding:2px; }
		FIELDSET IFRAME { width:100px; height:100px; }
	</style>
	<script type="text/javascript" src="../../dojo.js"
		data-dojo-config="isDebug: true"></script>

	<script type="text/javascript">
		// Global methods accessed by iframes
		var count, loading;
		function initIframeMethods(iframeWin, parentWin){
			iframeWin.frameElement.findInput = function(){ return parentWin._findInput(iframeWin); };
			iframeWin.frameElement.scrollMin = function(n){ parentWin._scroll(iframeWin,true,n); };
			iframeWin.frameElement.scrollMax = function(n){ parentWin._scroll(iframeWin,false,n); };
			iframeWin.frameElement.getBoundingRect = function(n){ return parentWin._getBoundingRect(iframeWin, n); };
			iframeWin.frameElement.getVisibleSize = function(n){ return parentWin._getVisibleSize(iframeWin, n); };
			iframeWin.frameElement.scrollIntoView = function(x,y,w,h){ parentWin._scrollIntoView(iframeWin,x,y,w,h); };
			iframeWin.frameElement.onClick = function(e){ parentWin._onClick(iframeWin);return false; };
		}

		function _findInput(win){
			return win.document.getElementById('it');
		}

		function _getBoundingRect(win, n){
			var r = n.getBoundingClientRect();
			return { left: r.left, right: r.right, top: r.top, bottom: r.bottom, w: Math.round(r.right - r.left), h: Math.round(r.bottom - r.top) };
		}

		function _scroll(win,isMin,n){
			while(n && n.tagName){
				n.scrollTop = isMin ? -9999 : 9999;
				n.scrollLeft = isMin ? -9999 : 9999;
				if(n.tagName == "BODY" && (n.scrollLeft || n.scrollTop)){
					break; // skip HTML
				}
				n = n.parentNode;
			}
		}

		var loaded = {};
		function iframeLoaded(id){
			if(!loaded[id]){	// ignore duplicate notifications
				loaded[id] = true;
				if(--count == 0){ loading.callback(true); }
			}
		}

		require([
			"doh",
			"dojo/dom", "dojo/dom-attr", "dojo/dom-geometry", "dojo/dom-style",
			"dojo/query", "dojo/sniff", "dojo/_base/window", "dojo/window", "dojo/_base/array", "dojo/domReady!"
		], function(doh, dom, domAttr, domGeom, domStyle, query, has, baseWin, winUtils, array) {

			// More global methods accessed by iframes
			_scrollIntoView = function(win,x,y,w,h){
				var n = _findInput(win);
				var pos;
				if(typeof x == "number" && typeof y == "number"){
					var p = baseWin.withGlobal(win, 'position', domGeom, [ n ]);
					pos = { x: p.x + x, y: p.y + y, w: isNaN(w) ? 1 : w, h: isNaN(h) ? 1 : h };
				}
				baseWin.withGlobal(win, 'scrollIntoView', winUtils, [ n, pos ]);
			};
			_onClick = function(win){
				_scrollIntoView(win);
			};

			_getVisibleSize = function(win,n){
				var	html = win.document.documentElement,
					body = win.document.body,
					rect = n.getBoundingClientRect(),
					width = Math.min(body.clientWidth || html.clientWidth, html.clientWidth || body.clientWidth),
					height = Math.min(body.clientHeight || html.clientHeight, html.clientHeight || body.clientHeight),
					pos = baseWin.withGlobal(win, 'position', domGeom, [ n ]);
				// adjust width and height for IE nonsense
				width += Math.round(rect.left - pos.x);
				height += Math.round(rect.top - pos.y);
				if(has('ie')){ width += outerScrollBarSize; } // IE10 bug
				for(y = 0; y < height; y++){
					for(x = 0; x < width; x++){
						var pointElement = win.document.elementFromPoint(x,y);
						if(pointElement == n){
							// work around browser bugs
							// Opera 12.12 says the element is showing beyond the browser edge
							// IE 10 says`
							for(var w = 1; (x+w) < width && win.document.elementFromPoint(x+w,y) == n; w++);
							for(var h = 1; (y+h) < height && win.document.elementFromPoint(x,y+h) == n; h++);
							return { w: w, h: h };
						}
					}
				}
				return { w: 0, h: 0 };
			};
			

			// Below is the magic code that creates the iframes from the given template.
			// This should be generalized for other files to include.

			function getIframeSrc(id, content, doctype, rtl){
				content = content.replace(/"/g/*balance"*/,"'").replace(/iframe.javascript/g,"text/javascript").replace(/<input\b/ig,"<INPUT disabled ");
				var iframeSrc = 'javascript:"';
				// find browser specific CSS attributes
				if(has("ie")){
					content = content.replace(/IE([A-Z]_)/g, "$1");
				}else if(has("webkit")){
					content = content.replace(/WK([A-Z]_)/g, "$1");
				}else if(has("mozilla")){
					content = content.replace(/MZ([A-Z]_)/g, "$1");
				}else if(has("opera")){
					content = content.replace(/OP([A-Z]_)/g, "$1");
				}
				// find DOCTYPE specific CSS attributes
				if(doctype=="strict"){
					iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>\n";
					content = content.replace(/[A-Z0-9_]*(\b|_)[SZ]_[A-Z0-9_]*/g, "");
				}else if(doctype=="loose"){
					iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n";
					content = content.replace(/[A-Z0-9_]*(\b|_)[TZ]_[A-Z0-9_]*/g, "");
				}else{
					if(has("webkit")){
						iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"; // quirks: needed for WebKit's javascript: protocol
					}
					content = content.replace(/[A-Z0-9_]*(\b|_)[QZ]_[A-Z0-9_]*/g, "");
				}
				if(rtl){
					content = content.replace(/[A-Z0-9_]*(\b|_)R_[A-Z0-9_]*/g, "");
				}else{
					content = content.replace(/[A-Z0-9_]*(\b|_)L_[A-Z0-9_]*/g, "");
				}
				content = content.replace(/\s*<(\/?)iframestyle>\s*/ig,"<$1"+"STYLE>");
				var i = content.indexOf('<STYLE>');
				var style = '';
				if(i >= 0){
					var j = content.indexOf('</STYLE>');
					if(j >= 0){
						style = content.substring(i+7, j);
						content = content.substr(j+8);
					}
				}
				iframeSrc +=
				'<HTML dir='+(rtl?'rtl':'ltr')+'>'+
				'<HEAD>'+
					'<STYLE>'+
						'* { border:0px solid white;padding:0px;margin:0px;font-style:normal;font-family:monospace;font-size:0px;line-height:normal; }\n'+
						'INPUT { display:block;background-color:red;font-size:0px;line-height:0px;overflow:hidden;width:20px;height:20px; }\n'+
						'UL { list-style-type: none;line-height:0px;width:45px;overflow:auto; }\n'+
						'LI { list-style-type: none;line-height:20px;overflow:visible;max-width:20px;max-height:20px;height:20px;width:20px;float:left; }\n'+
						'HR { width:120px;height:1px;visibility:hidden;display:block; }\n'+
						style+
					'<\/STYLE>'+
				'<\/HEAD>'+
				'<BODY BGCOLOR=#ffffff>'+
					content+
					'<SCRIPT type=text/javascript>'+
						'win=frameElement.ownerDocument.defaultView||frameElement.document.parentWindow;'+
						'win.initIframeMethods(window, win);'+
						'win.iframeLoaded(\'' + id + "-" + doctype + "-" + (rtl ?'rtl':'ltr') + '\');'+
						'document.body.onclick=frameElement.onClick;'+
					'<\/SCRIPT>'+
				'<\/BODY>'+
				'<\/HTML>"';
				return iframeSrc;
			}

			function makeIframe(id, className, style, content, doctype, rtl, srcNode){
				var iframeSrc = getIframeSrc(id, content, doctype, rtl);
				var container = document.createElement('fieldset');
				var text = (doctype=="strict"? 'strict': (doctype=="loose"? 'loose' : 'quirks')) + (rtl? ' RTL' : '');
				var color = (rtl? 'medium': '') + (doctype=="strict"? 'SpringGreen': (doctype=="loose"? 'Turquoise' : 'Aquamarine'));
				var idSuffix = (doctype=="strict"? '_strict': (doctype=="loose"? '_loose': '_quirks')) + (rtl? '_rtl' : '');
				domStyle.set(container, "cssText", "display:inline;border:1px ridge gray;padding:0px;margin:0px;background-color:"+color+";text-align:"+(rtl?"right;":"left;"));
				container.appendChild(document.createTextNode(text));
				var iframe = document.createElement('iframe');
				iframe.setAttribute('src', iframeSrc);
				iframe.setAttribute('frameBorder', "0");
				iframe.setAttribute('scrolling', "auto");
				iframe.setAttribute('allowTransparency', "true");
				iframe.setAttribute('id', id + idSuffix);
				iframe.setAttribute('name', id + idSuffix);
				iframe.className = className;
				domStyle.set(iframe, "cssText", "visibility:hidden;display:block;border:2px solid "+color+";background-color:transparent;margin:0px;padding:3px;"+style);
				container.appendChild(iframe);
				srcNode.appendChild(container);
				var src = iframe.getAttribute("src");
				if(!src || src.indexOf("javascript") == -1){
					// set it again if it didn't stick the first time: esp. older Opera and WebKit
					setTimeout(function(){ iframe.setAttribute('src', iframeSrc); }, 0);
				}
			}

			var innerScrollBarSize = Math.ceil(dom.byId("nonscroll").clientWidth - dom.byId("withscroll").clientWidth);
			console.debug('inner scrollbar size = ' + innerScrollBarSize);
			var outerScrollBarSize = Math.ceil((has("ie") >= 9) ? ((domGeom.position(document.documentElement).w - document.documentElement.clientWidth) || innerScrollBarSize) : innerScrollBarSize);
			console.debug('outer scrollbar size = ' + outerScrollBarSize);

			doh.register("dojo.window.scroll",[
				{
					name: "create iframes and wait for them to load",
					timeout: 20000,
					runTest: function(){
						loading = new doh.Deferred();
						var testIframes = query('DIV[type="testIframe"]');
						count = testIframes.length * 4;
						console.log("count is " + count);
						// have to do all the iframes at once so the iPad doesn't resize and cause problems
						for(var i=0; i < testIframes.length; i++){
							var srcNode = testIframes[i];
							var content = srcNode.innerHTML || '';
							var id = srcNode.id || "";
							var style = srcNode.getAttribute('style') || "";
							var className = srcNode.getAttribute('class') || srcNode.className || "";
							if(typeof style == "object"){
								style = style.cssText || "";
							}
							srcNode.innerHTML = "";
							srcNode.removeAttribute('style');
							srcNode.className = "";

							makeIframe(id, className, style, content, "strict", false, srcNode);
							makeIframe(id, className, style, content, "quirks", false, srcNode);
							makeIframe(id, className, style, content, "loose", true, srcNode);
							makeIframe(id, className, style, content, "quirks", true, srcNode);
						}
						return loading;
					}
				},
				function checkAttrs(){
					var body = baseWin.body();
					winUtils.scrollIntoView(body);
					doh.f(domAttr.has(body,'_offsetParent'));
					doh.f(domAttr.has(body,'_parent'));
				}
			]);
                        array.forEach([	'8249',
					'8284',
					'absContent',
					'fixedNode',
					'fixedScrollable',
					'7036_8665',
					'innerNoScrollBars',
					'noScrollBars',
					'table',
					'innerScrollbars',
					'8542',
					'tooBig',
					'htmlPadding' ],
				function(test){
                        		array.forEach([	"_strict", "_quirks", "_loose_rtl", "_quirks_rtl" ],
						function(mode){
							var	id = test+mode,
								n, maxWidth, maxHeight, nodeWidth, nodeHeight, rAfterScroll, vAfterScroll, rBeforeScroll, vBeforeScroll;
							doh.register(id, [
							{
								timeout: 4000,
								name: "compare to native",
								runTest: function(){ with(dom.byId(id)){
									n = findInput();
									scrollMin(n);
									var d = new doh.Deferred();
									setTimeout(function(){
										rBeforeScroll = getBoundingRect(n);
										vBeforeScroll = getVisibleSize(n);
										nodeWidth = rBeforeScroll.w;
										nodeHeight = rBeforeScroll.h;
										dom.byId(id).style.visibility = 'visible';
										n.scrollIntoView(true);
										setTimeout(function(){
											var vAfterNativeScroll = getVisibleSize(n);
											scrollIntoView();
											setTimeout(d.getTestCallback(function(){
												vAfterScroll = getVisibleSize(n);
												doh.t(vAfterScroll.w > 0, "min width " + vAfterScroll.w);
												doh.t(vAfterScroll.h > 0, "min height " + vAfterScroll.h);
												doh.t(vAfterScroll.w >= vAfterNativeScroll.w, "width compare " + vAfterNativeScroll.w + " to " + vAfterScroll.w);
												doh.t(vAfterScroll.h >= vAfterNativeScroll.h, "height compare " + vAfterNativeScroll.h + " to " + vAfterScroll.h);
												maxWidth = Math.max(vAfterNativeScroll.w, vAfterScroll.w);
												maxHeight = Math.max(vAfterNativeScroll.h, vAfterScroll.h);
											}), 0);
										}, 0);
									}, 0);
									return d;
								}}
							},
							{
								timeout: 4000,
								name: "min start horizontal",
								runTest: function(){ with(dom.byId(id)){
									scrollMin(n);
									var d = new doh.Deferred();
									setTimeout(function(){
										scrollIntoView(1,0);
										setTimeout(function(){
											rAfterScroll = getBoundingRect(n);
											vAfterScroll = getVisibleSize(n);
											if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so all but leftmost pixel on first row is showing
												scrollIntoView(0,0);
												setTimeout(d.getTestCallback(function(){
													doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "min: start: shift right partial width");
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "min: start: shift right full width");
												}), 0);
											}else if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so only 2 leftmost pixels on first row are showing
												scrollIntoView(nodeWidth-1,0);
												setTimeout(d.getTestCallback(function(){
													doh.is(2, vAfterScroll.w, "min: start: shift left width");
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "min: start: shift left full width");
												}), 0);
											}else{ // no horizontal scrolling
												scrollIntoView(0,0,nodeWidth);
												setTimeout(d.getTestCallback(function(){
													vAfterScroll = getVisibleSize(n);
													doh.is(maxWidth, vAfterScroll.w, "min: start: no shift full width");
												}), 0);
											}
										}, 0);
									}, 0);
									return d;
								}}
							},
							{
								timeout: 2000,
								name: "min start vertical",
								runTest: function(){ with(dom.byId(id)){
									var d = new doh.Deferred();
									if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so all rows are showing
										scrollIntoView(1,nodeHeight-1);
										setTimeout(d.getTestCallback(function(){
											doh.is(vAfterScroll.h, maxHeight, "min: start: shift down height");
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "min: start: shift down full height");
										}), 0);
									}else if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so only the first row is showing
										scrollIntoView(0,nodeHeight-1);
										setTimeout(d.getTestCallback(function(){
											doh.is(1, vAfterScroll.h, "min: start: shift up height");
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "min: start: shift up full height");
										}), 0);
									}else{ // no vertical scrolling
										scrollIntoView(0,nodeHeight-1);
										setTimeout(d.getTestCallback(function(){
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "min: start: no shift full height");
										}), 0);
									}
									return d;
								}}
							},
							{
								timeout: 4000,
								name: "min end horizontal",
								runTest: function(){ with(dom.byId(id)){
									scrollMin(n);
									var d = new doh.Deferred();
									setTimeout(function(){
										scrollIntoView(nodeWidth-2,nodeHeight-1);
										setTimeout(function(){
											rAfterScroll = getBoundingRect(n);
											vAfterScroll = getVisibleSize(n);
											if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so all but rightmost pixel on first row is showing
												scrollIntoView(nodeWidth-1,nodeHeight-1);
												setTimeout(d.getTestCallback(function(){
													doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "min: end: shift left partial width");
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "min: end: shift left full width");
												}), 0);
											}else if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so only 2 rightmost pixels on first row are showing
												scrollIntoView(0,nodeHeight-1);
												setTimeout(d.getTestCallback(function(){
													doh.is(2, vAfterScroll.w, "min: end: shift right width");
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "min: end: shift right full width");
												}), 0);
											}else{ // no horizontal scrolling
												scrollIntoView(0,nodeHeight-1,nodeWidth);
												setTimeout(d.getTestCallback(function(){
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "min: end: no shift full width");
												}), 0);
											}
										}, 0);
									}, 0);
									return d;
								}}
							},
							{
								timeout: 2000,
								name: "min end vertical",
								runTest: function(){ with(dom.byId(id)){
									var d = new doh.Deferred();
									if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so all rows are showing
										scrollIntoView(nodeWidth-1,0);
										setTimeout(d.getTestCallback(function(){
											doh.is(vAfterScroll.h, maxHeight, "min: end: shift up height");
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "min: end: shift up full height");
										}), 0);
									}else if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so only the last row is showing
										scrollIntoView(0,0);
										setTimeout(d.getTestCallback(function(){
											doh.is(1, vAfterScroll.h, "min: end: shift down height");
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "min: end: shift down full height");
										}), 0);
									}else{ // no vertical scrolling
										scrollIntoView(0,nodeHeight-1);
										setTimeout(d.getTestCallback(function(){
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "min: end: no shift full height");
										}), 0);
									}
									return d;
								}}
							},
							{
								timeout: 4000,
								name: "max start horizontal",
								runTest: function(){ with(dom.byId(id)){
									scrollMax(n);
									var d = new doh.Deferred();
									setTimeout(function(){
										rBeforeScroll = getBoundingRect(n);
										vBeforeScroll = getVisibleSize(n);
										scrollIntoView(1,0);
										setTimeout(function(){
											rAfterScroll = getBoundingRect(n);
											vAfterScroll = getVisibleSize(n);
											if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so all but leftmost pixel on first row is showing
												scrollIntoView(0,0);
												setTimeout(d.getTestCallback(function(){
													doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "max: start: shift right partial width");
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "max: start: shift right full width");
												}), 0);
											}else if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so only 2 leftmost pixels on first row are showing
												scrollIntoView(nodeWidth-1,0);
												setTimeout(d.getTestCallback(function(){
													doh.is(2, vAfterScroll.w, "max: start: shift left width");
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "max: start: shift left full width");
												}), 0);
											}else{ // no horizontal scrolling
												scrollIntoView(0,0,nodeWidth);
												setTimeout(d.getTestCallback(function(){
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "max: start: no shift full width");
												}), 0);
											}
										}, 0);
									}, 0);
									return d;
								}}
							},
							{
								timeout: 2000,
								name: "max start vertical",
								runTest: function(){ with(dom.byId(id)){
									var d = new doh.Deferred();
									if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so all rows are showing
										scrollIntoView(1,nodeHeight-1);
										setTimeout(d.getTestCallback(function(){
											doh.is(vAfterScroll.h, maxHeight, "max: start: shift down height");
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "max: start: shift down full height");
										}), 0);
									}else if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so only the first row is showing
										scrollIntoView(0,nodeHeight-1);
										setTimeout(d.getTestCallback(function(){
											doh.is(1, vAfterScroll.h, "max: start: shift up height");
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "max: start: shift up full height");
										}), 0);
									}else{ // no vertical scrolling
										scrollIntoView(0,nodeHeight-1);
										setTimeout(d.getTestCallback(function(){
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "max: start: no shift full height");
										}), 0);
									}
									return d;
								}}
							},
							{
								timeout: 4000,
								name: "max end horizontal",
								runTest: function(){ with(dom.byId(id)){
									scrollMax(n);
									var d = new doh.Deferred();
									setTimeout(function(){
										scrollIntoView(nodeWidth-2,nodeHeight-1);
										setTimeout(function(){
											rAfterScroll = getBoundingRect(n);
											vAfterScroll = getVisibleSize(n);
											if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so all but rightmost pixel on first row is showing
												scrollIntoView(nodeWidth-1,nodeHeight-1);
												setTimeout(d.getTestCallback(function(){
													doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "max: end: shift left partial width");
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "max: end: shift left full width");
												}), 0);
											}else if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so only 2 rightmost pixels on first row are showing
												scrollIntoView(0,nodeHeight-1);
												setTimeout(d.getTestCallback(function(){
													doh.is(2, vAfterScroll.w, "max: end: shift right width");
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "max: end: shift right full width");
												}), 0);
											}else{ // no horizontal scrolling
												scrollIntoView(0,nodeHeight-1,nodeWidth);
												setTimeout(d.getTestCallback(function(){
													vAfterScroll = getVisibleSize(n);
													doh.is(vAfterScroll.w, maxWidth, "max: end: no shift full width");
												}), 0);
											}
										}, 0);
									}, 0);
									return d;
								}}
							},
							{
								timeout: 2000,
								name: "max end vertical",
								runTest: function(){ with(dom.byId(id)){
									var d = new doh.Deferred();
									if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so all rows are showing
										scrollIntoView(nodeWidth-1,0);
										setTimeout(d.getTestCallback(function(){
											doh.is(vAfterScroll.h, maxHeight, "max: end: shift up height");
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "max: end: shift up full height");
										}), 0);
									}else if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so only the last row is showing
										scrollIntoView(0,0);
										setTimeout(d.getTestCallback(function(){
											doh.is(1, vAfterScroll.h, "max: end: shift down height");
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "max: end: shift down full height");
										}), 0);
									}else{ // no vertical scrolling
										scrollIntoView(0,0);
										setTimeout(d.getTestCallback(function(){
											vAfterScroll = getVisibleSize(n);
											doh.is(vAfterScroll.h, maxHeight, "max: end: no shift full height");
										}), 0);
									}
									return d;
								}}
							}]);
						}
					);
				} 
			);

			doh.run();
		});
	</script>
</head>
<body>
<h1>Automated scrollIntoView tests with 3 different DOCTYPEs as well as right-to-left</h1>
<!-- compute scrollbar size for test result computations -->
<table style="visibility:hidden;table-layout:fixed;">
<tr><td><div id="nonscroll"  style="width:100px;overflow:hidden;border:1px solid blue;">&nbsp;</div></td></tr>
<tr><td><div id="withscroll" style="width:100px;overflow-x:hidden;overflow-y:scroll;border:1px solid red;">&nbsp;</div></td></tr>
</table>
<!--	The test templates are below -->
<fieldset>
<label for="8249">Scrollable parent != offsetParent:</label>
<div type="testIframe" id="8249">
	<iframestyle>INPUT { float:left; }
		HTML, BODY { overflow: hidden; }
	</iframestyle>
	<div style="height:61px;width:50px;overflow-y:scroll;margin:11px 20px"
		><p style="display:inline;"
		><li><input style="visibility:hidden;"></li
		><li><input style="visibility:hidden;"></li
		><li><input style="visibility:hidden;"></li
		><li><input id=it></li
		><li><input style="visibility:hidden;"></li
		><li><input style="visibility:hidden;"></li
		><li><input style="visibility:hidden;"></li
		></p
	></div>
</div>
</fieldset>
<fieldset>
<label for="8284">Absolute positioned overflow container:</label>
<div type="testIframe" id="8284">
	<iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle>
	<hr style="height:200px;width:20px;"/>
	<div style="position:absolute;top:0px;left:0px;height:200px;width:20px;">
		<input id=it style="margin:90px 0px;">
	</div>
</div>
</fieldset>
<fieldset>
<label for="absContent">Absolute-positioned content:</label>
<div type="testIframe" id="absContent">
	<iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle>
	<div style="height:200px;width:20px;"></div>
	<input id=it style="position:absolute;left:10px;top:90px;">
</div>
</fieldset>
<fieldset>
<label for="fixedNode">Fixed-positioned node:</label>
<div type="testIframe" id="fixedNode">
	<hr style="height:50px;float:left;"/>
	<hr style="height:50px;float:right;"/>
	<input id=it style="position:fixed;top:75px;left:-5px;">
</div>
</fieldset>
<fieldset>
<label for="fixedScrollable">Fixed-positioned scrollable content:</label>
<div type="testIframe" id="fixedScrollable">
	<iframestyle>HTML { overflow:hidden !important; /*IE6*/ }
		INPUT { height:20px; width:20px; }</iframestyle>
	<div style="height:100px;width:70px;overflow-y:scroll;position:fixed;top:0px;left:0;">
		<input id=it style="margin:120px 0px;">
		<hr style="width:10px;">
	</div>
	<hr style="height:200px;width:20px;"/>
</div>
</fieldset>
<fieldset>
<label for="7036_8665">Double scrollbars with absolute positioned content:</label>
<div type="testIframe" id="7036_8665">
	<iframestyle>INPUT { height:28px; width:28px; }</iframestyle>
	<div style="height:70px;width:70px;overflow-y:scroll;position:absolute;top:26px;left:5px;"
		><input id=it style="margin:80px 0px 80px 0px;"
		><hr style="width:10px;"
	></div>
	<div style="height:26px;width:10px;position:absolute;top:96px;left:10px;"></div>
</div>
</fieldset>
<fieldset>
<label for="innerNoScrollBars">Complex scrollable inner content, no scrollbars:</label>
<div type="testIframe" id="innerNoScrollBars">
	<iframestyle>BODY { overflow:hidden !important; /*IE9*/ }</iframestyle>
	<fieldset style="overflow:hidden; margin:10px;border:1px solid red;border-width:1px 2px 3px 4px;display:inline;"
	><div style="overflow:hidden; width:20px;height:20px;"
		><fieldset style="width:59px;overflow:visible;"
			><input style="background-color:green;height:15px;float:left;"
			><nobr style="margin:7px;padding:3px;border:5px solid black;overflow:visible;display:block;width:90px;float:left;"
				><input style="background-color:black;display:inline;width:24px;height:24px;float:left;"
				><input id=it style="display:inline;float:left;"
				><input style="background-color:blue;display:inline;width:16px;height:16px;float:left;"
			></nobr
			><input style="background-color:cyan;height:10px;float:left;"
		></fieldset
	></div
	></fieldset>
</div>
</fieldset>
<fieldset>
<label for="noScrollBars">Nothing to do:</label>
<div type="testIframe" id="noScrollBars">
	<iframestyle>
		HTML { overflow:hidden !important; /*IE6*/ }
		BODY { overflow:hidden !important; /*IE9*/ }
	</iframestyle>
	<input id=it style="margin:25px;">
</div>
</fieldset>
<fieldset>
<label for="table">Table:</label>
<div type="testIframe" id="table">
	<iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle>
	<table style="border-width:75px 5px 75px 5px;float:left;" cellspacing="0" cellpadding="0" rules="none">
		<tr><td><input id=it style="height:40px;width:40px;float:left;"></td></tr>
	</table>
</div>
</fieldset>
<fieldset>
<label for="innerScrollbars">Inner scrollable content with scrollbars:</label>
<div type="testIframe" id="innerScrollbars">
	<iframestyle>
		HTML { overflow:hidden !important; /*IE6*/ }
		BODY { padding:10px; }
		TABLE { OPR_float:left; }
	</iframestyle>
	<div style="overflow:scroll;height:80px;width:80px;"
		><fieldset style="visibility:hidden;"
			><table cellspacing="65" cellpadding="0" border="0"
				><tr><td><input id=it style="width:50px;height:50px;clear:both;float:left;visibility:visible;"></td></tr
			></table
		></fieldset
	></div>
</div>
</fieldset>
<fieldset>
<label for="8542">position:absolute TD content:</label>
<div type="testIframe" id="8542">
	<div style="position:absolute;padding:100px 20px;left:5px;">
		<table style="width:10px;height:10px;max-height:10px;table-layout:fixed;" cellspacing="0" cellpadding="0">
			<tr><td><div style="position:relative;height:10px;width:10px;"><input id=it style="position:absolute;"></div></td></tr>
		</table>
	</div>
</div>
</fieldset>
<fieldset>
<label for="tooBig">Oversized content:</label>
<div type="testIframe" id="tooBig">
	<iframestyle>
		HTML { IEZ_overflow:scroll !important; /*IE6*/ }
		BODY { OPT_overflow:scroll !important; }
	</iframestyle>
	<input id=it style="position:absolute;margin:-10px 0px 0px 0px;left:-20px;width:130px;height:130px;">
	<hr style="height:100px;width:200px;float:left;"/>
	<hr style="height:100px;width:200px;float:right;"/>
</div>
</fieldset>
<fieldset>
<label for="htmlPadding">HTML/BODY padding:</label>
<div type="testIframe" id="htmlPadding">
	<iframestyle>HTML, BODY { padding:50px 9px; }
		HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle>
	<hr style="height:50px;width:20px;"/>
	<input id=it style="display:block;clear:both;float:left;">
	<hr style="clear:both;height:50px;width:20px;"/>
</div>
</fieldset>
<br>
</body>
</html>
